package com.cql.service.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cql.common.core.DO.RegionDO;
import com.cql.common.core.DTO.CityDTO;
import com.cql.common.core.DTO.ProvinceDTO;
import com.cql.common.utils.StringUtils;
import com.cql.mapper.RegionMapper;
import com.cql.service.business.RegionService;
import com.cql.service.cache.CommonCacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author cql
 */
@Service("regionService")
public class RegionServiceImpl extends ServiceImpl<RegionMapper, RegionDO> implements RegionService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RegionMapper regionMapper;

    @Autowired
    private CommonCacheService commonCacheService;

    @Override
    public List<ProvinceDTO> listRegion() {
        /**
         * 先去redis中查询,没有再去数据库差
         */
        List<ProvinceDTO> regionByCache = commonCacheService.getRegionByCache();

        if (StringUtils.isNotEmpty(regionByCache)) {
            return regionByCache;
        }

        List<ProvinceDTO> result = new ArrayList<>();

        //1.获取所有省份
        QueryWrapper<RegionDO> wrapper = new QueryWrapper<>();
        wrapper.eq("level", 1);
        List<RegionDO> provinces = regionMapper.selectList(wrapper);
        for (RegionDO province : provinces) {
            ProvinceDTO p = new ProvinceDTO();
            p.setRegionId(province.getRegionId());
            p.setProvinceName(province.getName());
            result.add(p);
        }

        //2.查询省份下所有的城市
        for (ProvinceDTO provinceDTO : result) {
            provinceDTO.setCities(new ArrayList<>());
            QueryWrapper<RegionDO> wrapper_1 = new QueryWrapper<>();
            wrapper_1.eq("parent_id", provinceDTO.getRegionId());
            List<RegionDO> cities = regionMapper.selectList(wrapper_1);
            for (RegionDO city : cities) {
                CityDTO c = new CityDTO();
                BeanUtils.copyProperties(city, c);
                provinceDTO.getCities().add(c);
            }
        }

        //3.存入redis
        commonCacheService.insertRegion(result);

        return result;
    }

    @Override
    public List<CityDTO> listByNameOrPinyin(String text) {
        //1.从缓存中获取
        List<ProvinceDTO> provinces = commonCacheService.getRegionByCache();
        if (StringUtils.isEmpty(provinces)) {
            logger.error("listByNameOrPinyin 数据为空,可能会出现问题");
            return new ArrayList<CityDTO>();
        }

        List<CityDTO> result = new ArrayList<>();


        for (ProvinceDTO province : provinces) {
            List<CityDTO> cities = province.getCities();
            cities = cities.stream().filter(c -> {
                if (c.getName().contains(text)) {
                    return true;
                }
                if (c.getPinyin().startsWith(text, 0)) {
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
            result.addAll(cities);
        }

        return result;
    }

    @Override
    public List<RegionDO> getFullName(Long addr) {
        /**
         * 获取当前的，获取上级的
         */
        List<RegionDO> result = new ArrayList<>();
        RegionDO child = regionMapper.selectById(addr);
        if (StringUtils.isNull(child)) {
            return result;
        }
        if (child.getLevel() == 1) {
            result.add(child);
            return result;
        }

        QueryWrapper<RegionDO> wrapper = new QueryWrapper<>();
        wrapper.eq("level", 1);
        wrapper.eq("region_id", child.getParentId());

        RegionDO parent = regionMapper.selectOne(wrapper);
        if (StringUtils.isNull(parent)) {
            result.add(child);
            return result;
        } else {
            result.add(parent);
            result.add(child);
        }

        return result;
    }
}